package com.qfedu.edu.iotserver.utils;

public class SnowflakeIdGenerator {
    private static final long START_TIMESTAMP = 1640995200000L; // 起始时间
    private static final long WORKER_ID_BITS = 5L; // 机器 ID 位数
    private static final long DATACENTER_ID_BITS = 5L; // 数据中心 ID 位数
    private static final long MAX_WORKER_ID = -1L ^ (-1L << WORKER_ID_BITS);
    private static final long MAX_DATACENTER_ID = -1L ^ (-1L << DATACENTER_ID_BITS);
    private static final long SEQUENCE_BITS = 12L; // 序列号位数

    private long workerId; // 机器 ID
    private long datacenterId; // 数据中心 ID
    private long sequence = 0L; // 生成序列
    private long lastTimestamp = -1L; // 上一次生成 ID 的时间戳

    public SnowflakeIdGenerator(long workerId, long datacenterId) {
        if (workerId > MAX_WORKER_ID || workerId < 0 || datacenterId > MAX_DATACENTER_ID || datacenterId < 0) {
            throw new IllegalArgumentException("Worker ID or Datacenter ID is invalid");
        }
        this.workerId = workerId;
        this.datacenterId = datacenterId;
    }

    public synchronized long nextId() {
        long timestamp = System.currentTimeMillis();
        if (timestamp < lastTimestamp) {
            throw new RuntimeException("Clock moved backwards. Refusing to generate id");
        }
        if (lastTimestamp == timestamp) {
            sequence = (sequence + 1) & (-1L ^ (-1L << SEQUENCE_BITS));
        } else {
            sequence = 0L;
        }
        lastTimestamp = timestamp;

        return ((timestamp - START_TIMESTAMP) << (WORKER_ID_BITS + DATACENTER_ID_BITS + SEQUENCE_BITS))
                | (datacenterId << (WORKER_ID_BITS + SEQUENCE_BITS))
                | (workerId << SEQUENCE_BITS)
                | sequence;
    }
}

